package com.jiantong.work.impl.service;

import com.google.common.base.Throwables;
import com.google.common.collect.Maps;
import com.jiantong.common.util.UserUtil;
import com.jiantong.user.ext.LoginUser;
import com.jiantong.work.enums.DocumentsDeleteFlag;
import com.jiantong.work.impl.dao.BreedReportsFormDao;
import com.jiantong.work.model.BreedReportsForm;
import com.jiantong.work.service.BreedReportsFormReadService;
import io.terminus.boot.rpc.common.annotation.RpcProvider;
import io.terminus.common.model.PageInfo;
import io.terminus.common.model.Paging;
import io.terminus.common.model.Response;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * Created by niufei on 2017/4/11.
 */
@Slf4j
@Service
@RpcProvider
public class BreedReportsFormReadServiceImpl implements BreedReportsFormReadService {

    private final BreedReportsFormDao breedReportsFormDao;

    @Autowired
    public BreedReportsFormReadServiceImpl(BreedReportsFormDao breedReportsFormDao) {
        this.breedReportsFormDao = breedReportsFormDao;
    }

    @Override
    public Response<List<Map<String, BigDecimal>>> findSumGroupByBreedType(Date start, Date end, Long breedFactoryId) {
        try {
            Map<String, Object> criteria = Maps.newHashMap();
            if (start != null) {
                criteria.put("start", start);
            }
            if (end != null) {
                criteria.put("end", end);
            }
            List<Long> breedFactoryIds = new ArrayList<>();
            if (breedFactoryId != null) {
                breedFactoryIds.add(breedFactoryId);
            } else {
                LoginUser loginUser = UserUtil.getCurrentUser();
                breedFactoryIds = loginUser.getBreedFactoryIds();
            }
            if(!breedFactoryIds.isEmpty()) criteria.put("breedFactoryIds", breedFactoryIds);
            else return Response.ok(new ArrayList<>());

            criteria.put("deleteFlag", DocumentsDeleteFlag.NORMAL.value());
            List<Map<String, BigDecimal>> list = breedReportsFormDao.findSumGroupByBreedType(criteria);
            if (list == null) {
                log.error("Sum(applyReportIds={}) is not found");
                return Response.fail("Sum.not.found");
            }
            BigDecimal quantitySum = new BigDecimal(0);
            BigDecimal qualifiedQuantitySum = new BigDecimal(0);
            BigDecimal unqualifiedQuantitySum = new BigDecimal(0);

            for (Map<String, BigDecimal> aList : list) {
                quantitySum = quantitySum.add(aList.get("quantity"));
                qualifiedQuantitySum = qualifiedQuantitySum.add(aList.get("qualifiedQuantity"));
                unqualifiedQuantitySum = unqualifiedQuantitySum.add(aList.get("unqualifiedQuantity"));
            }
            Map<String, BigDecimal> map = Maps.newHashMap();
            map.put("breedType", new BigDecimal(10000));
            map.put("unit", null);
            map.put("quantity", quantitySum);
            map.put("qualifiedQuantity", qualifiedQuantitySum);
            map.put("unqualifiedQuantity", unqualifiedQuantitySum);
            list.add(map);
            return Response.ok(list);
        } catch (Exception e) {
            log.error("failed to find Sum(), cause:{}", Throwables.getStackTraceAsString(e));
            return Response.fail("Sum.find.fail");
        }
    }

    @Override
    public Response<List<Map<String, BigDecimal>>> findSum(Date start, Date end, Integer breedType) {
        try {
            Map<String, Object> criteria = Maps.newHashMap();
            if (start != null) {
                criteria.put("start", start);
            }
            if (end != null) {
                criteria.put("end", end);
            }
            if (breedType != null) {
                criteria.put("breedType", breedType);
            }

            LoginUser loginUser = UserUtil.getCurrentUser();
            List<Long> breedFactoryIds = new ArrayList<>();
            breedFactoryIds = loginUser.getBreedFactoryIds();
            if(!breedFactoryIds.isEmpty()) criteria.put("breedFactoryIds", breedFactoryIds);
            else return Response.ok(new ArrayList<>());

            criteria.put("deleteFlag", DocumentsDeleteFlag.NORMAL.value());
            List<Map<String, BigDecimal>> list = breedReportsFormDao.findSum(criteria);
            if (list == null) {
                log.error("Sum normal(breedType={}) is not found", breedType);
                return Response.fail("Sum.normal.not.found");
            }
            return Response.ok(list);
        } catch (Exception e) {
            log.error("failed to find Sum normal (breedType={}), cause:{}", breedType, Throwables.getStackTraceAsString(e));
            return Response.fail("Sum.normal.find.fail");
        }
    }

    @Override
    public Response<List<Map<String, Integer>>> findSumByIsToLocal(Date start, Date end, Integer breedType) {
        try {
            Map<String, Object> criteria = Maps.newHashMap();
            if (start != null) {
                criteria.put("start", start);
            }

            if (end != null) {
                criteria.put("end", end);
            }
            if (breedType != null) {
                criteria.put("breedType", breedType);
            }

            LoginUser loginUser = UserUtil.getCurrentUser();
            List<Long> breedFactoryIds = new ArrayList<>();
            breedFactoryIds = loginUser.getBreedFactoryIds();

            if(!breedFactoryIds.isEmpty()) criteria.put("breedFactoryIds", breedFactoryIds);
            else return Response.ok(new ArrayList<>());

            criteria.put("deleteFlag", DocumentsDeleteFlag.NORMAL.value());
            List<Map<String, Integer>> list = breedReportsFormDao.findSumByIsToLocal(criteria);
            if (list == null) {
                log.error("SumByIsToLocal(breedType={}) is not found", breedType);
                return Response.fail("SumByIsToLocal.not.found");
            }
            return Response.ok(list);
        } catch (Exception e) {
            log.error("failed to find SumByIsToLocal (breedType={}), cause:{}", breedType, Throwables.getStackTraceAsString(e));
            return Response.fail("SumByIsToLocal.normal.find.fail");
        }
    }

    @Override
    public Response<List<Map<String, BigDecimal>>> findSumGroupByButcherFactory(Date start, Date end, Integer breedType) {
        try {
            Map<String, Object> criteria = Maps.newHashMap();
            if (start != null) {
                criteria.put("start", start);
            }
            if (end != null) {
                criteria.put("end", end);
            }
            if (breedType != null) {
                criteria.put("breedType", breedType);
            }
            criteria.put("isToLocal", 1);
            LoginUser loginUser = UserUtil.getCurrentUser();
            List<Long> breedFactoryIds = new ArrayList<>();
            breedFactoryIds = loginUser.getBreedFactoryIds();
            if(!breedFactoryIds.isEmpty()) criteria.put("breedFactoryIds", breedFactoryIds);
            else return Response.ok(new ArrayList<>());

            criteria.put("deleteFlag", DocumentsDeleteFlag.NORMAL.value());
            List<Map<String, BigDecimal>> list = breedReportsFormDao.findSumGroupByButcherFactory(criteria);
            if (list == null) {
                log.error("SumGroupByButcherFactory(breedType={}) is not found", breedType);
                return Response.fail("SumGroupByButcherFactory.not.found");
            }
            return Response.ok(list);
        } catch (Exception e) {
            log.error("failed to find SumGroupByButcherFactory (breedType={}), cause:{}", breedType, Throwables.getStackTraceAsString(e));
            return Response.fail("SumGroupByButcherFactory.normal.find.fail");
        }
    }

    @Override
    public Response<List<Map<String, BigDecimal>>> findSumGroupByBreedFactoryTown(Date start, Date end, Integer breedType) {
        try {
            Map<String, Object> criteria = Maps.newHashMap();
            if (start != null) {
                criteria.put("start", start);
            }
            if (end != null) {
                criteria.put("end", end);
            }
            if (breedType != null) {
                criteria.put("breedType", breedType);
            }
            LoginUser loginUser = UserUtil.getCurrentUser();
            List<Long> breedFactoryIds = new ArrayList<>();
            breedFactoryIds = loginUser.getBreedFactoryIds();
            if(!breedFactoryIds.isEmpty()) criteria.put("breedFactoryIds", breedFactoryIds);
            else return Response.ok(new ArrayList<>());

            criteria.put("deleteFlag", DocumentsDeleteFlag.NORMAL.value());
            List<Map<String, BigDecimal>> list = breedReportsFormDao.findSumGroupByBreedFactoryTown(criteria);
            if (list == null) {
                log.error("SumGroupByBreedFactoryTown(breedType={}) is not found", breedType);
                return Response.fail("SumGroupByBreedFactoryTown.not.found");
            }
            return Response.ok(list);
        } catch (Exception e) {
            log.error("failed to find SumGroupByBreedFactoryTown (breedType={}), cause:{}", breedType, Throwables.getStackTraceAsString(e));
            return Response.fail("SumGroupByBreedFactoryTown.normal.find.fail");
        }
    }

    @Override
    public Response<Paging<BreedReportsForm>> pagingBreedReportsForm(Integer pageNo, Integer pageSize, Date start, Date end, Integer breedType) {
        try {
            PageInfo pageInfo = new PageInfo(pageNo, pageSize);
            Map<String, Object> criteria = Maps.newHashMap();
            if (start != null) {
                criteria.put("start", start);
            }
            if (end != null) {
                criteria.put("end", end);
            }

            if (breedType != null) {
                criteria.put("breedType", breedType);
            }
            LoginUser loginUser = UserUtil.getCurrentUser();
            List<Long> breedFactoryIds = new ArrayList<>();
            breedFactoryIds = loginUser.getBreedFactoryIds();
            if(!breedFactoryIds.isEmpty()) criteria.put("breedFactoryIds", breedFactoryIds);
            else return Response.ok(new Paging<>(0L,new ArrayList<>()));
            return Response.ok(breedReportsFormDao.pagingBreedReportsForm(pageInfo.getOffset(), pageInfo.getLimit(), criteria));
        } catch (Exception e) {
            log.error("failed to paging BreedReportsForm, cause:{}", Throwables.getStackTraceAsString(e));
            return Response.fail("BreedReportsForm.paging.fail");
        }
    }

    @Override
    public Response<BreedReportsForm> findById(Long id) {
        try {
            BreedReportsForm breedReportsForm = breedReportsFormDao.findById(id);
            if (breedReportsForm == null) {
                log.error("breedReportsForm(id={}) is not found", id);
                return Response.fail("breedReportsForm.not.found");
            }
            return Response.ok(breedReportsForm);
        } catch (Exception e) {
            log.error("failed to find breedReportsForm(id={}), cause:{}", id, Throwables.getStackTraceAsString(e));
            return Response.fail("breedReportsForm.find.fail");
        }
    }

    /**
     * 产地检疫总情况
     * @param criteria
     * @return
     */
    @Override
    public Response<List<Map>> cdjy(Map criteria) {
        try {
            return Response.ok(breedReportsFormDao.cdjy(criteria));
        } catch (Exception e) {
            log.error("failed to find breedReportsForm(id={}), cause:{}", Throwables.getStackTraceAsString(e));
            return Response.fail("breedReportsForm.find.fail");
        }
    }

    /**
     * 本地申报数
     * @param criteria
     * @return
     */
    @Override
    public Response<Integer> local(Map criteria) {
        try {
            return Response.ok(breedReportsFormDao.local(criteria));
        } catch (Exception e) {
            log.error("failed to find breedReportsForm(id={}), cause:{}", Throwables.getStackTraceAsString(e));
            return Response.fail("breedReportsForm.find.fail");
        }
    }

    /**
     * 去往本地屠宰场分布图
     * @param criteria
     * @return
     */
    @Override
    public Response<List<Map>> localbutcher(Map criteria) {
        try {
            return Response.ok(breedReportsFormDao.localbutcher(criteria));
        } catch (Exception e) {
            log.error("failed to find breedReportsForm(id={}), cause:{}", Throwables.getStackTraceAsString(e));
            return Response.fail("breedReportsForm.find.fail");
        }
    }
    @Override
    public Response<BreedReportsForm> findByReportId(Long reportId){
        try {
            return Response.ok(breedReportsFormDao.findByReportId(reportId));
        } catch (Exception e) {
            log.error("failed to find breedReportsForm(id={}), cause:{}", Throwables.getStackTraceAsString(e));
            return Response.fail("breedReportsForm.find.fail");
        }
    }

    /**
     * 分页查询
     *
     * @param criteria 参数
     * @return Paging<BreedReportsForm>
     */
    @Override
    public Response<Paging<BreedReportsForm>> pagingBreedReportsFormForWeb(Integer pageNo, Integer pageSize,Map<String, Object> criteria) {
        try {
            PageInfo pageInfo = new PageInfo(pageNo, pageSize);
            return Response.ok(breedReportsFormDao.pagingBreedReportsForm(pageInfo.getOffset(), pageInfo.getLimit(), criteria));
        } catch (Exception e) {
            log.error("failed to paging BreedReportsForm, cause:{}", Throwables.getStackTraceAsString(e));
            return Response.fail("BreedReportsForm.paging.fail");
        }
    }

    @Override
    public Response<List<BreedReportsForm>> listBreedReportsFormForWeb(Map<String , Object> map) {
        try {
            return Response.ok(breedReportsFormDao.listBreedReportsFormForWeb(map));
        } catch (Exception e) {
            log.error("failed to paging BreedReportsForm, cause:{}", Throwables.getStackTraceAsString(e));
            return Response.fail("BreedReportsForm.paging.fail");
        }
    }
}
